import androidx.lifecycle.viewModelScope
import kotlinx.coroutines.launch
import models.LocationUi
import models.LocationsEvent
import models.LocationsViewState

class LocationsViewModel(
    private val repository: LocationsRepository
) : BaseViewModel<LocationsViewState, LocationsEvent>(
    initialState = LocationsViewState()
) {
    override fun obtainEvent(event: LocationsEvent) {
        when (event) {
            is LocationsEvent.AddLocation -> {
                updateState { it.copy(loadingStatus = LoadingStatus.Loading) }
                viewModelScope.launch {
                    repository.createLocation(event.name)
                        .onSuccess { load() }
                        .onFailure { t ->
                            updateState { it.copy(loadingStatus = LoadingStatus.Error(t.message)) }
                        }
                }
            }

            is LocationsEvent.DeleteLocation -> {
                updateState { it.copy(loadingStatus = LoadingStatus.Loading) }
                viewModelScope.launch {
                    repository.deleteLocation(event.id)
                        .onSuccess { load() }
                        .onFailure { t ->
                            updateState { it.copy(loadingStatus = LoadingStatus.Error(t.message)) }
                        }

                }
            }

            LocationsEvent.LoadLocations -> load()
            is LocationsEvent.LocationSelected -> {
                updateState { it.copy(selectedLocation = event.location) }
            }
        }
    }

    private fun load() {
        updateState { it.copy(loadingStatus = LoadingStatus.Loading) }
        viewModelScope.launch {
            repository.locations()
                .onSuccess { resp ->
                    updateState {
                        it.copy(
                            loadingStatus = LoadingStatus.Idle,
                            locations = resp.map(LocationUi::from)
                        )
                    }
                }
                .onFailure { t ->
                    updateState { it.copy(loadingStatus = LoadingStatus.Error(t.message)) }
                }
        }
    }
}